package com.fowo.api.sys.service.impl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fowo.api.common.model.RException;
import com.fowo.api.sys.entity.SysDict;
import com.fowo.api.sys.entity.SysDictItem;
import com.fowo.api.sys.mapper.SysDictItemMapper;
import com.fowo.api.sys.mapper.SysDictMapper;
import com.fowo.api.sys.model.*;
import com.fowo.api.sys.service.SysDictService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 系统字典服务实现
 * @author yl_ls
 */
@Service
public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> implements SysDictService {
    private static List<SysDictAllItem> CACHE_ALL_ITEMS;
    @Resource
    private SysDictItemMapper itemMapper;

    @Override
    public Page<SysDictItemVo> pageSearch(SysDictSearchParamPo searchParamPo) {
        return baseMapper.pageSearch(searchParamPo.toPage(), searchParamPo);
    }

    private void dictCodeRepeatCheck(String dictCode, Long id) {
        if (baseMapper.exists(Wrappers.<SysDict>query().eq("dict_code", dictCode).ne(id != null, "id", id))) {
            throw new RException("此字典代码已经存在！");
        }
    }

    private void dictItemValueRepeatCheck(Long dictId, String itemValue, Long id) {
        if (StringUtils.isEmpty(itemValue)) {
            throw new RException("字典值不能为空！");
        }
        if (itemMapper.exists(Wrappers.<SysDictItem>query()
                .eq("dict_id", dictId)
                .eq("item_value", itemValue)
                .ne(id != null, "id", id)
        )) {
            throw new RException("此字典项值已经存在！");
        }
    }

    @Override
    public boolean delete(List<Long> idList) {
        CACHE_ALL_ITEMS = null;
        return baseMapper.delete(Wrappers.<SysDict>query()
                .in("id", idList)
                .ne("is_protected", "1")
        ) > 0;
    }

    @Override
    public boolean create(CreateSysDictPo createSysDictPo) {
        dictCodeRepeatCheck(createSysDictPo.getDictCode(), null);
        CACHE_ALL_ITEMS = null;
        SysDict entity = new SysDict();
        BeanUtils.copyProperties(createSysDictPo, entity);
        entity.setHidden(false);
        entity.doCreate();
        return save(entity);
    }

    @Override
    public boolean update(SysDict updateSysDict) {
        final SysDict entity = getById(updateSysDict.getId());
        if (entity == null || Boolean.TRUE.equals(entity.isProtected())) {
            return false;
        }
        dictCodeRepeatCheck(updateSysDict.getDictCode(), updateSysDict.getId());
        CACHE_ALL_ITEMS = null;
        updateSysDict.doUpdate();
        return updateById(updateSysDict);
    }

    @Override
    public Page<SysDictItem> itemPageSearch(SysDictItemSearchParamPo searchParamPo) {
        return baseMapper.itemPageSearch(searchParamPo.toPage(), searchParamPo);
    }

    @Override
    public boolean createItem(CreateSysDictItemPo createSysDictItemPo) {
        dictItemValueRepeatCheck(createSysDictItemPo.getDictId(), createSysDictItemPo.getItemValue(), null);
        CACHE_ALL_ITEMS = null;
        final SysDict dict = getById(createSysDictItemPo.getDictId());
        if (dict == null) {
            throw new RException("指定 dictId 未找到");
        }
        SysDictItem sysDictItem = new SysDictItem();
        BeanUtils.copyProperties(createSysDictItemPo, sysDictItem);
        if (sysDictItem.getStatus() == null) {
            sysDictItem.setStatus(0);
        }
        sysDictItem.doCreate();
        return itemMapper.insert(sysDictItem) > 0;
    }

    @Override
    public boolean updateItem(SysDictItem updateSysDictItem) {
        dictItemValueRepeatCheck(updateSysDictItem.getDictId(), updateSysDictItem.getItemValue(), updateSysDictItem.getId());
        CACHE_ALL_ITEMS = null;
        final SysDict dict = getById(updateSysDictItem.getDictId());
        if (dict == null) {
            throw new RException("指定 dictId 未找到");
        }
        updateSysDictItem.doUpdate();
        return itemMapper.updateById(updateSysDictItem) > 0;
    }

    @Override
    public boolean deleteItem(List<Long> idList) {
        CACHE_ALL_ITEMS = null;
        return itemMapper.delete(Wrappers.<SysDictItem>query()
                .in("id", idList)
                .ne("is_protected", "1")
        ) > 0;
    }

    @Override
    public List<SysDictAllItem> getAllItems() {
        if (CACHE_ALL_ITEMS != null) {
            return CACHE_ALL_ITEMS;
        }
        return CACHE_ALL_ITEMS = itemMapper.selectAllItems();
    }

    @Override
    public List<SysDictAllItem> getDictItems(String code) {
        return getAllItems().stream().filter(i -> i.getDictCode().equals(code)).collect(Collectors.toList());
    }
}
